#include "core/monitor.h"
#include <spdlog/spdlog.h>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <chrono>
#include <cstring>

namespace hft {

// MonitorFactory 实现
std::shared_ptr<Monitor> MonitorFactory::createMonitor(const std::string& name) {
    auto& creators = getCreators();
    auto it = creators.find(name);
    if (it == creators.end()) {
        spdlog::error("Monitor not found: {}", name);
        return nullptr;
    }
    return it->second();
}

void MonitorFactory::registerMonitor(const std::string& name, 
                                   std::function<std::shared_ptr<Monitor>()> creator) {
    auto& creators = getCreators();
    if (creators.find(name) != creators.end()) {
        spdlog::warn("Monitor already registered: {}", name);
        return;
    }
    creators[name] = creator;
    spdlog::info("Registered monitor: {}", name);
}

std::unordered_map<std::string, std::function<std::shared_ptr<Monitor>()>>& 
MonitorFactory::getCreators() {
    static std::unordered_map<std::string, std::function<std::shared_ptr<Monitor>()>> creators;
    return creators;
}

// PerformanceMonitor 实现
PerformanceMonitor::PerformanceMonitor() {
    // 初始化性能指标
    metrics_ = PerformanceMetrics();
}

bool PerformanceMonitor::init(const YAML::Node& config) {
    try {
        const auto& monitor_config = config["trading"]["performance"];
        
        // 读取导出配置
        export_config_.type = monitor_config["export"]["type"].as<std::string>();
        export_config_.path = monitor_config["export"]["path"].as<std::string>();
        export_config_.format = monitor_config["export"]["format"].as<std::string>();

        spdlog::info("Performance monitor initialized with export config:");
        spdlog::info("Type: {}", export_config_.type);
        spdlog::info("Path: {}", export_config_.path);
        spdlog::info("Format: {}", export_config_.format);

        return true;
    } catch (const std::exception& e) {
        spdlog::error("Failed to initialize performance monitor: {}", e.what());
        return false;
    }
}

void PerformanceMonitor::onMarketData(const MarketDataMessage& data) {
    // 性能监控不需要处理行情数据
}

void PerformanceMonitor::onTrade(const Trade& trade) {
    // 记录交易
    trades_.push_back(trade);

    // 更新性能指标
    calculateReturns();
    calculateDrawdowns();
    calculateConsecutiveWinsLosses();
    metrics_.sharpe_ratio = calculateSharpeRatio();
    metrics_.win_rate = calculateWinRate();
    metrics_.profit_factor = calculateProfitFactor();
}

void PerformanceMonitor::onPosition(const Position& position) {
    // 性能监控不需要处理持仓更新
}

void PerformanceMonitor::onAccount(const Account& account) {
    account_ = account;
}

YAML::Node PerformanceMonitor::getData() const {
    YAML::Node data;
    data["total_return"] = metrics_.total_return;
    data["annual_return"] = metrics_.annual_return;
    data["max_drawdown"] = metrics_.max_drawdown;
    data["sharpe_ratio"] = metrics_.sharpe_ratio;
    data["win_rate"] = metrics_.win_rate;
    data["profit_factor"] = metrics_.profit_factor;
    data["max_consecutive_wins"] = metrics_.max_consecutive_wins;
    data["max_consecutive_losses"] = metrics_.max_consecutive_losses;
    return data;
}

bool PerformanceMonitor::exportData(const std::string& path) {
    try {
        YAML::Node data = getData();
        std::ofstream file(path);
        if (!file.is_open()) {
            spdlog::error("Failed to open file for export: {}", path);
            return false;
        }
        file << data;
        return true;
    } catch (const std::exception& e) {
        spdlog::error("Failed to export performance data: {}", e.what());
        return false;
    }
}

void PerformanceMonitor::calculateReturns() {
    if (trades_.empty()) return;

    // 计算每笔交易的收益率
    std::vector<double> trade_returns;
    for (const auto& trade : trades_) {
        double pnl = trade.price * trade.volume;
        if (trade.direction == OrderDirection::SELL) {
            pnl = -pnl;
        }
        trade_returns.push_back(pnl);
    }

    // 计算总收益率
    metrics_.total_return = std::accumulate(trade_returns.begin(), trade_returns.end(), 0.0);

    // 计算年化收益率
    double days = (trades_.back().timestamp - trades_.front().timestamp).count() / (24.0 * 3600.0 * 1e9);
    metrics_.annual_return = metrics_.total_return / days * 252.0;

    // 保存收益率序列
    metrics_.returns = trade_returns;
}

void PerformanceMonitor::calculateDrawdowns() {
    if (metrics_.returns.empty()) return;

    // 计算权益曲线
    std::vector<double> equity;
    double current_equity = 0.0;
    for (double ret : metrics_.returns) {
        current_equity += ret;
        equity.push_back(current_equity);
    }

    // 计算回撤
    std::vector<double> drawdowns;
    double peak = equity[0];
    for (double e : equity) {
        if (e > peak) {
            peak = e;
        }
        double drawdown = (peak - e) / peak;
        drawdowns.push_back(drawdown);
    }

    // 计算最大回撤
    metrics_.max_drawdown = *std::max_element(drawdowns.begin(), drawdowns.end());

    // 保存回撤序列
    metrics_.drawdowns = drawdowns;
}

double PerformanceMonitor::calculateSharpeRatio() const {
    if (metrics_.returns.empty()) return 0.0;

    // 计算收益率均值和标准差
    double mean = std::accumulate(metrics_.returns.begin(), metrics_.returns.end(), 0.0) / metrics_.returns.size();
    double variance = 0.0;
    for (double ret : metrics_.returns) {
        variance += (ret - mean) * (ret - mean);
    }
    variance /= metrics_.returns.size();
    double std_dev = std::sqrt(variance);

    // 计算夏普比率
    return mean / std_dev * std::sqrt(252.0);
}

double PerformanceMonitor::calculateWinRate() const {
    if (trades_.empty()) return 0.0;

    // 计算盈利交易次数
    int winning_trades = 0;
    for (const auto& trade : trades_) {
        double pnl = trade.price * trade.volume;
        if (trade.direction == OrderDirection::SELL) {
            pnl = -pnl;
        }
        if (pnl > 0) {
            winning_trades++;
        }
    }

    // 计算胜率
    return static_cast<double>(winning_trades) / trades_.size();
}

double PerformanceMonitor::calculateProfitFactor() const {
    if (trades_.empty()) return 0.0;

    // 计算总盈利和总亏损
    double total_profit = 0.0;
    double total_loss = 0.0;
    for (const auto& trade : trades_) {
        double pnl = trade.price * trade.volume;
        if (trade.direction == OrderDirection::SELL) {
            pnl = -pnl;
        }
        if (pnl > 0) {
            total_profit += pnl;
        } else {
            total_loss += std::abs(pnl);
        }
    }

    // 计算盈亏比
    return total_loss == 0.0 ? 0.0 : total_profit / total_loss;
}

void PerformanceMonitor::calculateConsecutiveWinsLosses() {
    if (trades_.empty()) return;

    // 计算连续盈亏次数
    int current_wins = 0;
    int current_losses = 0;
    int max_wins = 0;
    int max_losses = 0;

    for (const auto& trade : trades_) {
        double pnl = trade.price * trade.volume;
        if (trade.direction == OrderDirection::SELL) {
            pnl = -pnl;
        }

        if (pnl > 0) {
            current_wins++;
            current_losses = 0;
            max_wins = std::max(max_wins, current_wins);
        } else {
            current_losses++;
            current_wins = 0;
            max_losses = std::max(max_losses, current_losses);
        }
    }

    metrics_.max_consecutive_wins = max_wins;
    metrics_.max_consecutive_losses = max_losses;
}

// RiskMonitor 实现
RiskMonitor::RiskMonitor() {
    // 初始化风险指标
    metrics_ = RiskMetrics();
}

bool RiskMonitor::init(const YAML::Node& config) {
    try {
        const auto& monitor_config = config["trading"]["risk"];
        
        // 读取导出配置
        export_config_.type = monitor_config["export"]["type"].as<std::string>();
        export_config_.path = monitor_config["export"]["path"].as<std::string>();
        export_config_.format = monitor_config["export"]["format"].as<std::string>();

        spdlog::info("Risk monitor initialized with export config:");
        spdlog::info("Type: {}", export_config_.type);
        spdlog::info("Path: {}", export_config_.path);
        spdlog::info("Format: {}", export_config_.format);

        return true;
    } catch (const std::exception& e) {
        spdlog::error("Failed to initialize risk monitor: {}", e.what());
        return false;
    }
}

void RiskMonitor::onMarketData(const MarketDataMessage& data) {
    // 更新价格数据
    auto& price_data = price_data_[data.symbol];
    price_data.prices.push_back(data.last_price);
    if (price_data.prices.size() > 100) { // 保留最近100个价格
        price_data.prices.erase(price_data.prices.begin());
    }

    // 更新最高最低价
    if (data.last_price > price_data.high) {
        price_data.high = data.last_price;
    }
    if (data.last_price < price_data.low || price_data.low == 0) {
        price_data.low = data.last_price;
    }

    // 更新收盘价
    price_data.close = data.last_price;

    // 检查风险指标
    checkRiskMetrics();
}

void RiskMonitor::onTrade(const Trade& trade) {
    // 更新风险指标
    checkRiskMetrics();
}

void RiskMonitor::onPosition(const Position& position) {
    positions_[position.symbol] = position;
    checkRiskMetrics();
}

void RiskMonitor::onAccount(const Account& account) {
    account_ = account;
    checkRiskMetrics();
}

YAML::Node RiskMonitor::getData() const {
    YAML::Node data;
    data["max_position"] = metrics_.max_position;
    data["max_margin_ratio"] = metrics_.max_margin_ratio;
    data["max_drawdown"] = metrics_.max_drawdown;
    data["max_volatility"] = metrics_.max_volatility;
    data["var_95"] = metrics_.var_95;
    data["var_99"] = metrics_.var_99;

    // 导出各品种的波动率和VaR
    YAML::Node symbol_metrics;
    for (const auto& [symbol, volatility] : metrics_.symbol_volatilities) {
        YAML::Node symbol_data;
        symbol_data["volatility"] = volatility;
        symbol_data["var"] = metrics_.symbol_vars.at(symbol);
        symbol_metrics[symbol] = symbol_data;
    }
    data["symbol_metrics"] = symbol_metrics;

    return data;
}

bool RiskMonitor::exportData(const std::string& path) {
    try {
        YAML::Node data = getData();
        std::ofstream file(path);
        if (!file.is_open()) {
            spdlog::error("Failed to open file for export: {}", path);
            return false;
        }
        file << data;
        return true;
    } catch (const std::exception& e) {
        spdlog::error("Failed to export risk data: {}", e.what());
        return false;
    }
}

void RiskMonitor::checkRiskMetrics() {
    // 更新最大持仓
    for (const auto& [symbol, position] : positions_) {
        double total_position = position.long_volume + position.short_volume;
        metrics_.max_position = std::max(metrics_.max_position, total_position);
    }

    // 更新最大保证金比例
    if (account_.balance > 0) {
        double margin_ratio = account_.margin / account_.balance;
        metrics_.max_margin_ratio = std::max(metrics_.max_margin_ratio, margin_ratio);
    }

    // 更新最大回撤
    if (account_.balance > 0) {
        double drawdown = (account_.balance - account_.available) / account_.balance;
        metrics_.max_drawdown = std::max(metrics_.max_drawdown, drawdown);
    }

    // 更新各品种的波动率和VaR
    for (const auto& [symbol, price_data] : price_data_) {
        double volatility = calculateVolatility(symbol);
        metrics_.symbol_volatilities[symbol] = volatility;
        metrics_.max_volatility = std::max(metrics_.max_volatility, volatility);

        double var_95 = calculateVaR(symbol, 0.95);
        double var_99 = calculateVaR(symbol, 0.99);
        metrics_.symbol_vars[symbol] = var_95;
        metrics_.var_95 = std::max(metrics_.var_95, var_95);
        metrics_.var_99 = std::max(metrics_.var_99, var_99);
    }
}

double RiskMonitor::calculateVolatility(const std::string& symbol) const {
    auto it = price_data_.find(symbol);
    if (it == price_data_.end() || it->second.prices.size() < 2) {
        return 0.0;
    }

    const std::vector<double>& prices = it->second.prices;
    std::vector<double> returns;
    for (size_t i = 1; i < prices.size(); ++i) {
        double ret = (prices[i] - prices[i-1]) / prices[i-1];
        returns.push_back(ret);
    }

    // 计算收益率的标准差
    double mean = std::accumulate(returns.begin(), returns.end(), 0.0) / returns.size();
    double variance = 0.0;
    for (double ret : returns) {
        variance += (ret - mean) * (ret - mean);
    }
    variance /= returns.size();

    // 年化波动率
    return std::sqrt(variance) * std::sqrt(252.0);
}

double RiskMonitor::calculateVaR(const std::string& symbol, double confidence_level) const {
    auto it = price_data_.find(symbol);
    if (it == price_data_.end() || it->second.prices.size() < 2) {
        return 0.0;
    }

    const std::vector<double>& prices = it->second.prices;
    std::vector<double> returns;
    for (size_t i = 1; i < prices.size(); ++i) {
        double ret = (prices[i] - prices[i-1]) / prices[i-1];
        returns.push_back(ret);
    }

    // 计算收益率的分位数
    std::sort(returns.begin(), returns.end());
    size_t index = static_cast<size_t>(returns.size() * (1 - confidence_level));
    return -returns[index] * std::sqrt(252.0); // 年化VaR
}

CtpMarketDataReceiver::CtpMarketDataReceiver() = default;
CtpMarketDataReceiver::~CtpMarketDataReceiver() { stop(); }

bool CtpMarketDataReceiver::init(const YAML::Node& config) {
    config_ = config;
    const auto& ctp_cfg = config["trading"]["market_data"]["provider"]["ctp"];
    front_address_ = ctp_cfg["front_address"].as<std::string>();
    user_id_ = ctp_cfg["user_id"].as<std::string>();
    password_ = ctp_cfg["password"].as<std::string>();
    broker_id_ = ctp_cfg["broker_id"].as<std::string>();
    app_id_ = ctp_cfg["app_id"].as<std::string>();
    auth_code_ = ctp_cfg["auth_code"].as<std::string>();
    return true;
}

bool CtpMarketDataReceiver::start() {
    if (api_) return true;
    api_.reset(CThostFtdcMdApi::CreateFtdcMdApi());
    callback_ = std::make_unique<CtpCallback>(this);
    api_->RegisterSpi(callback_.get());
    api_->RegisterFront(const_cast<char*>(front_address_.c_str()));
    api_->Init();
    spdlog::info("CTP MarketDataReceiver started.");
    return true;
}

void CtpMarketDataReceiver::stop() {
    if (api_) {
        api_->RegisterSpi(nullptr);
        api_->Release();
        api_.reset();
        callback_.reset();
        spdlog::info("CTP MarketDataReceiver stopped.");
    }
}

bool CtpMarketDataReceiver::subscribe(const std::string& symbol) {
    if (!api_) return false;
    char* instruments[1];
    instruments[0] = const_cast<char*>(symbol.c_str());
    int ret = api_->SubscribeMarketData(instruments, 1);
    return ret == 0;
}

bool CtpMarketDataReceiver::unsubscribe(const std::string& symbol) {
    if (!api_) return false;
    char* instruments[1];
    instruments[0] = const_cast<char*>(symbol.c_str());
    int ret = api_->UnSubscribeMarketData(instruments, 1);
    return ret == 0;
}

} // namespace hft 